#include "jeu.h"
#include <iostream>

jeu* creerJeu()
{
    jeu* jeux;
    jeux=new(jeu);	///On alloue la mémoire
    initJeu(jeux);	///et on l'initialise
    return jeux;
}

void initJeu(jeu* jeu)
{
     liste_niveau* A;
     Hero* h;
     tableau_monstre* tmon;
     tableau_arme* Ta;
     int* x;
     int* y;
     x=new(int);
     y=new(int);
     A=creerListeNiveauFichier("niveau"); ///On crée une liste de niveau
     jeuSetListeNiveau(jeu,A); ///qu'on initialise
     jeuRechercheDebutNiveau(jeu,1,x,y);
     Ta=creerTabArme("arme");/// On crée un tableau d'armes
     jeuSetTableauArme(jeu,Ta);
     h=creerHero(*x,*y,1,2,Ta[0].a); ///On crée un hero avec (temporairement) une position en x=2, en y=9, un nombre de pv=1 et et un nombre de vie=3
     jeuSetHero(jeu,h); ///On l'initialise sur le jeu(i.e. onle place sur un terrain dans un niveau).
     tmon=creerTableauMonstre("monstre");/// On crée un tableau de monstres
     jeuSetTableauMonstre(jeu,tmon);/// et on place les monstres dans le jeu
     delete(x);
     delete(y);
}

void supprimeJeu(jeu* jeu)
{
    supprimeListeNiveau(jeuGetListeNiveau(jeu)); ///on supprime la liste de niveau
    supprimeHero(jeuGetHero(jeu)); /// et le hero
    supprimeTableauMonstre(jeuGetTableauMonstre(jeu));
    supprimeTabArme(jeuGetTableauArme(jeu));
    delete(jeu); /// puis on efface de la memoire
}

Hero* jeuGetHero(jeu* jeu)
{
      return jeu->hero;
}

liste_niveau* jeuGetListeNiveau(jeu* jeu)
{
      return jeu->lniv;
}

void jeuSetHero(jeu* jeu,Hero* hero)
{
     jeu->hero=hero;
}

void jeuSetListeNiveau(jeu* jeu,liste_niveau* lniv)
{
     jeu->lniv=lniv;
}

void jeuActionClavier(jeu* jeu,const char touche)
{
     Niveau* niv;
     niv=jeuGetNiveau(jeu);	///on recupère le numéro du niveau
     switch(touche)
     {
                   case 'g':/// Si le joueur appuie sur la flèche gauche le héros essaye d'aller à gauche
                        heroGauche(jeuGetHero(jeu), niv);
                        break;
                   case 'd':/// Si le joueur appuie sur la flèche droite le héros essaye d'aller à droite
                        heroDroite(jeuGetHero(jeu), niv);
                        break;
                   case 'h':/// Si le joueur appuie sur la flèche haut le héros essaye de monter
                        heroHaut(jeuGetHero(jeu), niv);
                        break;
                   case 'b':/// Si le joueur appuie sur la flèche bas le héros essaye de descendre
                        heroBas(jeuGetHero(jeu), niv);
                        break;
                   case 's':///Si le joueru appuis sur la barre espace le héros essaye de sortir du niveau
                        heroSort(jeuGetHero(jeu), niv);
                        break;
     }
}

Terrain* jeuGetTerrain(jeu* jeu)
{
         return lnivChercheTerrain(jeuGetListeNiveau(jeu),heroGetniveau(jeuGetHero(jeu)),heroGetterrain(jeuGetHero(jeu)));
}

Niveau* jeuGetNiveau(jeu* jeu)
{
         return lnivChercheNiveau(jeuGetListeNiveau(jeu),heroGetniveau(jeuGetHero(jeu)));
}

void jeuRechercheDebutNiveau(jeu* jeu,int niv,int* x,int* y)
{
    Terrain* ter;
    ter=lnivChercheTerrain(jeuGetListeNiveau(jeu),niv,1);///On récupère le premier terrain du niveau
    RechercheDebutTerrain(ter,x,y);/// et le debut du terrain
}

tableau_monstre* jeuGetTableauMonstre(jeu* jeu)
{
                 return jeu->tmon;
}

tableau_arme* jeuGetTableauArme(jeu* jeu)
{
                 return jeu->tarme;
}

void jeuSetTableauMonstre(jeu* jeu,tableau_monstre* tmon)
{
     jeu->tmon=tmon;
}

void jeuSetTableauArme(jeu* jeu,tableau_arme* tarme)
{
     jeu->tarme=tarme;
}

void jeuTrieTableauMonstre(jeu* jeu)
{
     trieTableauMonstre(jeuGetTableauMonstre(jeu));
}

int jeuChercheMonstreTerrain(jeu* jeu,int niv, int ter,int* nbrMon)
{
		int x;
        x=chercheMonstreTerrain(jeuGetTableauMonstre(jeu),niv,ter,nbrMon);///On cherche combien il y a de monstre sur le terrain et la position du 1er par rapport au tableau de monstre
        return x;
}

void attaque(jeu* jeu)
{
	char c;
	int i,p;
	int* nbrMon;
	Hero* h;

	nbrMon=new (int);///on alloue la place pour le nombre de monstres
    p=-1;
	h=jeuGetHero(jeu);///puis on recupère le héros
	c=heroGetDirection(h);///et sa direction
	tableau_monstre* tmon=jeuGetTableauMonstre(jeu);///ainsi que le tableau de monstre

	p=jeuChercheMonstreTerrain(jeu,heroGetniveau(h), heroGetterrain(h),nbrMon);///On recupère les monstres du terrain
        if(p != -1)///s'il y a des monstres
        {
		     for(i=0;i<*nbrMon;i++)///pour chaque monstre
		     {
                           switch(c)///suivant la direction du héros
							{
								case 'd':
									if((heroGetX(h)+1)==monstreGetX(tmon[p+i].mon) && heroGetY(h)==monstreGetY(tmon[p+i].mon))///on vérifie que le monstre est juste devant le héros (une case devant genre "monstre : je vais te rentrer dedans")
									{
										(tmon[p+i].mon->vie)=(tmon[p+i].mon->vie)-(h->a->degat);///le héros inflige des dégats si c'est le cas
										if((tmon[p+i].mon->vie)<=0)///et si le monstre n'a plus de points de vie
										{
											supprimeMonstre(tmon,monstreGetNum(tmon[p+i].mon));///il meurt : on le supprime du tableau
											h->score=h->score+10;///et le héros gagne des points ^^
									    }
									}
									break;
								case 'g':
									if((heroGetX(h)-1)==monstreGetX(tmon[p+i].mon) && heroGetY(h)==monstreGetY(tmon[p+i].mon))
									{
										(tmon[p+i].mon->vie)=(tmon[p+i].mon->vie)-(h->a->degat);
										if((tmon[p+i].mon->vie)<=0)
										{
											supprimeMonstre(tmon,monstreGetNum(tmon[p+i].mon));
											h->score=h->score+10;
									    }
									}
									break;
								case 'h':
									if(heroGetX(h)==monstreGetX(tmon[p+i].mon) && (heroGetY(h)-1)==monstreGetY(tmon[p+i].mon))
									{
										(tmon[p+i].mon->vie)=(tmon[p+i].mon->vie)-(h->a->degat);
										if((tmon[p+i].mon->vie)<=0)
										{
											supprimeMonstre(tmon,monstreGetNum(tmon[p+i].mon));
											h->score=h->score+10;
									    }
									}
									break;
								case 'b':
									if(heroGetX(h)==monstreGetX(tmon[p+i].mon) && (heroGetY(h)+1)==monstreGetY(tmon[p+i].mon))
									{
										(tmon[p+i].mon->vie)=(tmon[p+i].mon->vie)-(h->a->degat);
										if((tmon[p+i].mon->vie)<=0)
										{
											supprimeMonstre(tmon,monstreGetNum(tmon[p+i].mon));
											h->score=h->score+10;
									    }
									}
									break;
							}
             }
        }
        delete nbrMon;///on libère la place pour le nombre de monstres
}

void contact(jeu* jeu)
{
	int i,p;
	int* nbrMon;
	Hero* h;

	nbrMon=new (int);///on alloue la place pour le nombre de monstre
    p=-1;
	h=jeuGetHero(jeu);///on récupère le héros
	tableau_monstre* tmon=jeuGetTableauMonstre(jeu);///et le tableau de monstre

	p=jeuChercheMonstreTerrain(jeu,heroGetniveau(h), heroGetterrain(h),nbrMon);///On recupère les monstre du terrain
        if(p != -1)///s'il y a des monstres
        {
		     for(i=0;i<*nbrMon;i++)///pour chaque monstres
		     {
                if((heroGetX(h))==monstreGetX(tmon[p+i].mon) && heroGetY(h)==monstreGetY(tmon[p+i].mon))///on vérifie si le monstre est sur le héros (dans le sens où il lui est rentré dedans)
                {
                    h->pv=h->pv-25;///si c'est le cas, le héros se prend 25 de dommage
                    h->score=h->score-5;///il perd 5 points
                    if(h->pv<=0)///si le héros n'a plus de pv (Points de Vie pour les noob)
                    {
                        h->vie--;///le héros perd une vie
                        h->score=h->score-8;///il perd 8 points
                        h->pv=100;///et on réinitialise ses PV à 100
                    }
                }
             }
        }
        if(heroGetvie(h)<=0)///si le héro n'a plus de vie
        {
			heroSetAvancement(h,-1);///on affiche un truc genre "Game Over try again"
		}
        delete nbrMon;///on libère la place pour le nombre de monstres
}

void changementArmeHero(jeu* jeu,int id)
{
	arme* a;
	a=rechercheArme(jeuGetTableauArme(jeu), id);
	if(a!=NULL)
	{
		if(armeGetDebloque(a)==1)
		{
			heroSetarme(jeuGetHero(jeu),rechercheArme(jeuGetTableauArme(jeu), id));
		}
	}
}


void verifPosition(jeu* jeu)
{
	Hero* hero=jeuGetHero(jeu);
    Terrain* ter=jeuGetTerrain(jeu);
    tableau_arme* tarme=jeuGetTableauArme(jeu);
	if(terPosHeroOk(ter,heroGetX(hero),heroGetY(hero))==9)
	{
		debloqueArme(tarme);
		ter->ter[hero->x][hero->y]='.';

	}
	if(terPosHeroOk(ter,heroGetX(hero),heroGetY(hero))==8)///quand le héros va sur une pièce (il la ramasse automatiquement)
    {
		ter->ter[hero->x][hero->y]='.';///la pière "disparait" (logique -_-)
		hero->score=hero->score+5;///et le héros gagne 5 points
	}
	if(terPosHeroOk(ter,heroGetX(hero),heroGetY(hero))==7)/**et on teste si le hero peut revenir au terrain precedent*/
    {
                (hero->x)=terrainGetDimX(ter)-2;/// on le change de terrain
                (hero->terrain)--;
    }
    if(terPosHeroOk(ter,heroGetX(hero),heroGetY(hero))==6)/**et on teste si le hero peut revenir au terrain precedent*/
    {
                heroSetX(hero,1);
                (hero->terrain)++;/// on le change de terrain
    }
}
